﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Pixysoft.Framework.Configurations.Core
{
    class HtmlNodesCollection : IHtmlNodesCollection
    {
        string parentpath;

        int nestLevel = 0;



        List<IHtmlNode> list = new List<IHtmlNode>();

        int index = -1;

        public HtmlNodesCollection(List<IHtmlNode> list, string parentPath, int nestLevel)
        {
            this.list = list;
            this.parentpath = parentPath;
            this.nestLevel = nestLevel;
        }


        public IHtmlNode AddDeclaration(string rawAttribute)
        {
            HtmlDeclarationNode node = new HtmlDeclarationNode(rawAttribute, parentpath, nestLevel, list.Count);
            list.Add(node);
            return node;
        }

        public IHtmlNode Add(string elementName, string rawAttribute)
        {
            return Add(elementName, rawAttribute, null);
        }

        public IHtmlNode Add(string elementName, string rawAttribute, string text)
        {
            HtmlNode node = new HtmlNode(elementName, rawAttribute, parentpath, nestLevel, list.Count);
            node.Text = text;
            list.Add(node);
            return node;
        }

        public void Add(IHtmlNode node)
        {
            list.Add(node);
        }

        public void RemoveAll()
        {
            list.Clear();
        }

        public void Remove(string elementName)
        {
            foreach (IHtmlNode node in this[elementName])
            {
                list.Remove(node);
            }
        }

        public IHtmlNode this[int index]
        {
            get
            {
                if (index < 0 || index > list.Count - 1)
                    return null;

                return list[index];
            }
        }

        public IHtmlNodeCollection this[string elementName]
        {
            get
            {
                List<IHtmlNode> rlist = new List<IHtmlNode>();

                foreach (IHtmlNode node in list)
                {
                    if (string.Equals(node.ElementName, elementName, StringComparison.OrdinalIgnoreCase))
                        rlist.Add(node);
                }

                return new HtmlNodeCollection(rlist, parentpath, nestLevel);
            }
        }

        public int Count
        {
            get { return list.Count; }
        }

        public bool Contains(string elementName)
        {
            return this[elementName].Count > 0;
        }

        public IHtmlNode[] SearchByClass(string classid)
        {
            List<IHtmlNode> rlist = new List<IHtmlNode>();

            foreach (IHtmlNode node in list)
            {
                if (string.Equals(classid, node.HtmlClass))
                    rlist.Add(node);
                else
                    SearchByClass(node, rlist, classid);
            }

            return rlist.ToArray();
        }

        private void SearchByClass(IHtmlNode node, List<IHtmlNode> list, string classid)
        {
            foreach (IHtmlNode subnode in node.Nodes)
            {
                if (string.Equals(classid, subnode.HtmlClass, StringComparison.OrdinalIgnoreCase))
                {
                    list.Add(subnode);
                }
                else
                {
                    SearchByClass(subnode, list, classid);
                }
            }
        }

        public IHtmlNode[] SearchById(string id)
        {
            List<IHtmlNode> rlist = new List<IHtmlNode>();

            foreach (IHtmlNode node in list)
            {
                if (string.Equals(id, node.HtmlId))
                    rlist.Add(node);
                else
                    SearchById(node, rlist, id);
            }

            return rlist.ToArray();
        }

        private void SearchById(IHtmlNode node, List<IHtmlNode> list, string id)
        {
            foreach (IHtmlNode subnode in node.Nodes)
            {
                if (string.Equals(id, subnode.HtmlId, StringComparison.OrdinalIgnoreCase))
                {
                    list.Add(subnode);
                }
                else
                {
                    SearchById(subnode, list, id);
                }
            }
        }

        public string Serialize(bool indent)
        {
            StringBuilder builder = new StringBuilder();

            foreach (IHtmlNode node in list)
            {
                builder.Append(node.Serialize(indent));
            }

            return builder.ToString();
        }

        #region IEnumerable<IHtmlNode> 成员

        public IEnumerator<IHtmlNode> GetEnumerator()
        {
            return this;
        }

        #endregion

        #region IEnumerable 成员

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return this;
        }

        #endregion

        #region IEnumerator<IHtmlNode> 成员

        public IHtmlNode Current
        {
            get
            {
                return this[index];
            }
        }

        #endregion

        #region IDisposable 成员

        public void Dispose()
        {
            Reset();
        }

        #endregion

        #region IEnumerator 成员

        object System.Collections.IEnumerator.Current
        {
            get
            {
                return this[index];
            }
        }

        public bool MoveNext()
        {
            if (index >= list.Count - 1)
                return false;

            index++;

            return true;
        }

        public void Reset()
        {
            index = -1;
        }

        #endregion
    }
}
